home *** CD-ROM | disk | FTP | other *** search
- /*
- * aPLib compression library - the smaller the better :)
- *
- * C/C++ example (tested with BCC32, DJGPP, Watcom and VC++)
- *
- * Copyright (c) 1998-2000 by Joergen Ibsen / Jibz
- * All Rights Reserved
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <io.h>
- #include <conio.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <errno.h>
-
- // Compiler specific stuff
- #if defined DJGPP
-
- #include <file.h>
- #include "..\..\lib\djgpp\aplib.h"
- #define __cdecl
-
- #elif defined VC
-
- #include "..\..\lib\vc\aplib.h"
-
- #elif defined DLL
-
- #include "..\..\lib\dll\aplib.h"
-
- #else // assume WATCOM
-
- #include "..\..\lib\watcom\aplib.h"
-
- #endif
-
- // Possible errors
- enum { OPEN_ERR = 1, READ_ERR, SMALL_ERR, TMP_ERR,
- PACK_ERR, MEM_ERR, WRITE_ERR };
-
- // Program name and version
- char *versionstr = "aPLib-Pack";
-
- // Global variables used
- int infile = -1, outfile = -1;
- unsigned int infilesize, outfilesize;
- unsigned char *outbuffer = NULL, *inbuffer = NULL;
- unsigned char *testbuffer = NULL, *workbuffer = NULL;
-
- unsigned char rotator[] = "-\\|/";
- int rotatorpos = 0;
-
- // =========================================================================
- // MISC. FUNCTIONS
- // =========================================================================
-
- // Some I/O error handler :)
- void myerror(int n)
- {
- // Print out error information
- printf("\n\n\007ERR: ");
- switch (n)
- {
- case OPEN_ERR : printf("Unable to open input-file!\n"); break;
- case PACK_ERR : printf("An error occured while packing!\n"); break;
- case READ_ERR : printf("Unable to read from input-file!\n"); break;
- case TMP_ERR : printf("Unable to create 'APACKTMP.$$$'!\n"); break;
- case SMALL_ERR : printf("File is too small to pack!\n"); break;
- case MEM_ERR : printf("Not enough memory!\n"); break;
- case WRITE_ERR : printf("Unable to write to output-file!\n"); break;
- default : printf("An unknown error occured!\n");
- }
-
- // Free memory and close files
- if (outbuffer != NULL) free(outbuffer);
- if (inbuffer != NULL) free(inbuffer);
- if (testbuffer != NULL) free(testbuffer);
- if (workbuffer != NULL) free(workbuffer);
- if (infile != -1) close(infile);
- if (outfile != -1) close(outfile);
- remove("APACKTMP.$$$");
-
- // Exit with errorlevel = error no.
- exit(n);
- }
-
- void syntax()
- {
- printf(" Syntax: aPPack <input file> [output file]\n\n");
- }
-
- int __cdecl callback(unsigned int inpos, unsigned int outpos)
- {
- unsigned char ch;
- printf("\r%c Packing data -> %3d%%", rotator[rotatorpos], inpos * 100 / infilesize);
- rotatorpos = (rotatorpos + 1) & 0x0003;
-
- // Check for ESC-hit
- if (kbhit())
- {
- ch = getch();
- if (ch == 0) ch = getch();
- if (ch == 27)
- {
- return (0); // abort packing
- }
- }
- return (1); // continue packing
- }
-
- // =========================================================================
- // MAIN
- // =========================================================================
-
- int main(int argc, char *argv[])
- {
- int infilearg = 0, outfilearg = 0;
-
- unsigned int packedlength, an_error;
-
- int i;
- unsigned int j;
-
- // Write name and copyright notice
- printf("===============================================================================\n");
- printf("%-25s Copyright (c) 1998-2000 by Joergen Ibsen / Jibz\n", versionstr);
- printf(" All Rights Reserved\n");
- printf("===============================================================================\n\n");
-
- // Write syntax when not enough parameters
- if (argc < 2)
- {
- syntax();
- return(1);
- }
-
- // Parse command line
- for (i = 1; i < argc; i++)
- {
- if (infilearg != 0)
- {
- if (outfilearg == 0) outfilearg = i;
- } else infilearg = i;
- }
-
- // Print syntax if no in-file
- if (infilearg == 0)
- {
- syntax();
- return(1);
- }
-
- // Open input file
- printf("■ Opening files\n");
- if ((infile = open(argv[infilearg], O_RDONLY | O_BINARY)) == -1) myerror(OPEN_ERR);
-
- // Get file size and check it
- lseek(infile, 0, SEEK_SET);
- infilesize = filelength(infile);
- if (infilesize < 64) myerror(SMALL_ERR);
-
- printf(" - Data size : %u bytes\n", infilesize);
-
- // Create tmp file
- if ((outfile = open("APACKTMP.$$$", O_WRONLY | O_CREAT | O_BINARY | O_TRUNC, S_IREAD | S_IWRITE)) == -1) myerror(TMP_ERR);
-
- printf("■ Allocating memory\n");
- // Allocate memory for compression buffers
- if ((inbuffer = (unsigned char *) malloc(infilesize)) == NULL) myerror(MEM_ERR);
- if ((testbuffer = (unsigned char *) malloc(infilesize)) == NULL) myerror(MEM_ERR);
- if ((outbuffer = (unsigned char *) malloc(((infilesize*9)/8)+16)) == NULL) myerror(MEM_ERR);
-
- // Allocate work mem for the packer
- if ((workbuffer = (unsigned char *) malloc(aP_workmem_size(infilesize))) == NULL) myerror(MEM_ERR);
-
- // Read data into memory
- read(infile, inbuffer, infilesize);
-
- // Pack data
- if ((packedlength = aP_pack(inbuffer, outbuffer, infilesize, workbuffer, callback)) == 0) myerror(PACK_ERR);
-
- // Print out the 100% line :)
- printf("\r■ Packing data -> %u bytes\n", packedlength);
-
- // Write code to output file
- lseek(outfile, 0, SEEK_SET);
- write(outfile, outbuffer, packedlength);
- outfilesize = filelength(outfile);
-
- // Depack compressed data and compare to original
- printf("■ Depacking and comparing -> ");
- printf("Depacked %u bytes - ", aP_depack_asm(outbuffer, testbuffer));
-
- an_error = 0;
- for (j = 0; j < infilesize; j++) if (testbuffer[j] != inbuffer[j]) an_error = 1;
-
- if (an_error) printf("There were errors!\n"); else printf("Ok.\n");
-
- // Free memory for compression buffers
- printf("■ Freeing memory\n");
- if (outbuffer != NULL) free(outbuffer);
- if (inbuffer != NULL) free(inbuffer);
- if (testbuffer != NULL) free(testbuffer);
- if (workbuffer != NULL) free(workbuffer);
-
- // Close in and out files
- printf("■ Closing files\n");
- if (infile != -1) close(infile);
- if (outfile != -1) close(outfile);
-
- // Rename the output file into the right name
- if (outfilearg != 0)
- {
- if (remove(argv[outfilearg]) != 0) if (errno == EACCES) myerror(WRITE_ERR);
- if (rename("APACKTMP.$$$", argv[outfilearg]) != 0) myerror(WRITE_ERR);
- } else {
- printf(" - No output file specified ... writing to 'OUT.DAT'\n");
- if (remove("OUT.DAT") != 0) if (errno == EACCES) myerror(WRITE_ERR);
- if (rename("APACKTMP.$$$", "OUT.DAT") != 0) myerror(WRITE_ERR);
- }
-
- // Print out results
- printf("\nDone ... compression ratio: %d%% ", 100 - ((outfilesize * 100) / infilesize));
- printf("(%u bytes -> %u bytes)\n", infilesize, outfilesize);
-
- // We're happy :)
- return (0);
- }
-
- // =========================================================================
- // END
- // =========================================================================
-